<?php
/**
 * WordPress中文版 自动下载安装脚本
 * v3.0.1
 *
 * 作者：沙渺 http://shamiao.com
 * 脚本主页：http://shamiao.com/wp-downunzip
 **/

define('SCRIPT_VERSION', '3.0.1');

/**
 * 函数：currpath_url
 * 用途：检测本脚本所在的目录的URL。（也就是wordpress要安装到的位置）
 * 参数：无
 * 返回值：(string)要求的URL
 **/
function currpath_url() {
    static $pageURL;
    if (!empty($pageURL)) return $pageURL;
    $pageURL = 'http';
    if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
    $pageURL .= "://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
    }
    else {
        $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
    }
    $script_filename = basename($_SERVER['PHP_SELF']);
    $pos_filename = strpos($pageURL, $script_filename);
    if ($pos_filename !== FALSE) {
        $pageURL = substr($pageURL, 0, $pos_filename);
    }
    return $pageURL;
}

/**
 * 函数：http_request_detect
 * 用途：检测cURL、fopen、fsockopen三种HTTP请求方式是否可行
 * 参数：(string)$method = curl/fopen/fsockopen 指定检测哪一种 
 * 返回值：true/false
 **/
function http_request_detect($method) {
    static $status = array();
    if (isset($status[$method])) return $status[$method];
    switch ($method) {
    case 'curl':
        $status[$method] = extension_loaded('curl') ? true : false;
        break;
    case 'fopen':
        $status[$method] = get_cfg_var('allow_url_fopen') ? true : false;
        break;
        /*case 'fsockopen':
            $status[$method] = function_exists('fsockopen') ? true : false;
        break;*/
    default:
        return false;
    }
    return $status[$method];
}

/**
 * 函数：http_request
 * 用途：抓取一个网址的HTTP文件，（可选）并直接存为文件
 * 参数：
 *  (string)$url - URL
 *  (reference string)$errtxt - 返回值：错误信息
 *  (mixed false/string)$filename - 直接存盘使用的文件名，不使用直接存盘则给定false
 * 返回值：
 *  不直接存盘时成功 - (string)目标内容 
 *  直接存盘时成功 - true
 *  失败 - false
 * 注：尝试顺序是cURL->fopen->fsockopen. 
 * 注2：由于fsockopen已经需要allow_url_fopen为前提了，所以是否着急写这个的必要性暂时需要讨论
 **/
function http_request($url, &$errtxt, $filename=false) {
    if (empty($url)) return false;
    if (empty($filename)) $filename = false;

    if (http_request_detect('curl')) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        if ($filename) {
            $fp = fopen($filename, "w");
            curl_setopt($ch, CURLOPT_FILE, $fp);
        } else {
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        }
        $cdata = curl_exec($ch);
        curl_close($ch); if ($filename) fclose($fp);
        if ($cdata) {
            if ($filename) return true; else return $cdata;
        } else {
            $errtxt = "cURL报告错误：".curl_error($ch);
            return false;
        }
    } else if (http_request_detect('fopen')) {
        @$fp_remote = fopen($url, "rb");
        if ($fp_remote) {
            $file_contents = '';
            while (!feof($fp_remote)) {
                $file_contents .= fread($fp_remote, 8192);
            }
            fclose($fp_remote);
            if ($filename) {
                @$fp_local = fopen($filename, 'w');
                if ($fp_local) {
                    fwrite($fp_local, $file_contents);
                    fclose($fp_local);
                    return true;
                } else {
                    $errtxt = "写入本地文件错误 ";
                    $errtxt .= "No. ".$lasterr['type'].": ".$lasterr['message'];
                    return false;
                }
            } else {
                return $file_contents;
            }
        } else {
            $lasterr = error_get_last();
            $errtxt = "fopen抓取URL错误 ";
            $errtxt .= "No. ".$lasterr['type'].": ".$lasterr['message'];
            return false;
        }
    /*} else if (http_request_detect('fsockopen')) {
    // 必要性论证中*/
    } else {
        $errtxt = "您的PHP不支持cURL、fopen任何一种主动发起HTTP请求的方式。";
        return false;
    }
}

/**
 * 函数：valid_filename
 * 用途：检测一个磁盘上没有同名文件的可用文件名
 * 参数：无
 * 返回值：(string)文件名
 * 注：检测的规律是首先使用wp.zip，其次不断尝试wp1.zip, wp2.zip...直到找到为止。
 **/
function valid_filename() {
    if (!file_exists('wp.zip')) return 'wp.zip';
    $i = 1; while (file_exists('wp'.$i.'.zip')) {$i++;}
    return 'wp'.$i.'.zip';
}

/**
 * 函数：extract_detect
 * 用途：检测zip文件解压方式是否可行
 * 参数：(string)$method = zip/zlib 指定检测哪一种 
 * 返回值：true/false
 **/
function extract_detect($method) {
    static $status = array();
    if (isset($status[$method])) return $status[$method];
    switch ($method)
    {
    case 'zip':
        $status[$method] = extension_loaded('zip') ? true : false;
        break;
    default:
        return false;
    }
    return $status[$method];
}

/**
 * 函数：extract_file
 * 用途：解压缩文件
 * 参数：
 *  (string)$filename - 文件名
 *  (reference string)$errtxt - 返回值：错误信息
 * 返回值：成功-true 失败-false
 **/
function extract_file($filename, $errtxt) {
    if (extract_detect('zip')) {
        $zip = new ZipArchive;
        $success = $zip->open($filename);
        if ($success === true) $success = $zip->extractTo('./');
        $zip->close();
        if ($success === true) {
            return true;
        } else {
            if ($success === false) {
                $errtxt = "解压缩出错（zip库报告）";
            } else {
                $errtxt = "打开压缩包出错：Error code ".$success;
            }
            return false;
        }
    } else {
        $errtxt = "您的PHP不支持zip组件。";
    }
}

/**
 * 函数：fetch_wpinstpack
 * 用途：根据WordPress网站提供的version-check API获得最新更新的网址。
 * 参数：
 *  (string)$url - API的URL
 *  (string)$localeexpected - 期待的语种
 *  (reference string)$errtxt - 返回值：错误信息
 *  (reference string)$version - 返回值：版本号
 * 返回值：成功-WordPress安装包URL 失败-false
 * 注：只获取第一组的，剩余丢弃
 **/
function fetch_wpinstpack($url, $localeexpected, &$errtxt, &$version) {
    //var_dump(extension_loaded('curl'));
    $result_api = http_request($url, $httpreq_errtxt);
    if ($result_api) {
        $result_api = trim(str_replace(array("\r\n", "\r"), "\n", $result_api));
        $result_arr = explode("\n", $result_api);
        $package = $result_arr[2];
        $version = $result_arr[3];
        $locale = $result_arr[4];
        if (!empty($package)) {
            if ($locale == $localeexpected) {
                return $package;
            } else {
                $errtxt = "您选择的语言包尚未跟进最新版的WordPress。";
                return false;
            }
        } else {
            $errtxt = "WordPress API 返回值无效. (package字段为空)";
            return false;
        }
    } else {
        $errtxt = $httpreq_errtxt;
        return false;
    }
}

/**
 * 函数：install_init
 * 用途：安装前的准备工作
 * 参数、返回值：无
 * 工作列表: 
 *  1. 当前目录确定在脚本目录下面
 *  2. 寻找一个可用的wpXXX.zip作为临时文件
 **/
function install_init() {
    global $filename;
    $filename = valid_filename();
    chdir(dirname($_SERVER['SCRIPT_FILENAME']));
}

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WP安装包自动准备脚本</title>
<style type="text/css">
<!--
* {font-family: Tahoma, sans-serif; }
h1 {font-size: 28px; }
h2 {font-size: 24px; margin-top: 12px; margin-bottom: 12px; }
p {font-size: 13px; line-height: 16px; margin: 6px; }
a {color: #1B66E4; } 
a:visited {color: #C73FE9; }
.semi {font-size: 12px; font-weight: normal; }
.error {font-weight: bold; color: red; }
-->
</style>
</head>
<body>
<h1>WordPress安装包自动准备脚本<span class="semi">ver.<?php echo SCRIPT_VERSION; ?> by <a href="http://shamiao.com">沙渺</a></span></h1>
<?php if ($_POST['action'] == 'install') : ?>
<?php
/**
 * 前台函数：front_exiterror
 * 显示错误信息并退出
 * “安装进程”界面用
 **/
function front_exiterror($errtxt) {
    define('SPAN_ERR_START', '<span class="error">');
    define('SPAN_ERR_END', '</span>');
    echo SPAN_ERR_START . nl2br(htmlentities($errtxt, ENT_COMPAT, "utf-8")) . SPAN_ERR_END;
    echo '</p>';
    echo <<<ERROR_PROMPT
<h2>安装出错</h2>
<p>很抱歉，安装过程出错。请通过错误信息查找问题。</p>
<p>您可以：</p>
<p>1. 按 <input type="submit" name="Submit2" value="后退" onClick=history.go(-1)> 按钮返回；</p>
<p>2. 到 <a href="http://shamiao.com/wp-downunzip">脚本首页</a> 寻求帮助。</p>
ERROR_PROMPT;
    exit();
}

?>
<h2>安装进程</h2>
<?php
install_init();

function front_getsourceurl() {
    global $sourceurl;
    echo "<p>";
    $pkgdata = array("wpcng" => array(
        "packagename" => "WPCNG WordPress中文团队汉化版"
    ), "wpcng" => array()
);
    switch ($_POST['publish']) {
    case "wpcng":
        $packagename = "WPCNG WordPress中文团队汉化版";
        $apiurl = "http://api.wfans.org/check-wp-version/?locale=zh_CN";
        $locale = "zh_CN";
        break;
    case "cnoffical":
        $packagename = "WordPress官方中文版";
        $apiurl = "http://api.wordpress.org/core/version-check/1.5/?locale=zh_CN";
        $locale = "zh_CN";
        break;
    case "enoffical":
        $packagename = "WordPress官方英文版";
        $apiurl = "http://api.wordpress.org/core/version-check/1.5/?locale=en_US";
        $locale = "en_US";
        break;
    case "custom":
        $sourceurl = $_POST['custurl'];
        $packagename = "";
        $apiurl = NULL;
        break;
    default:
        front_exiterror("表单数据无效。(publish字段)");
        break;
    }
    if (isset($apiurl)) {
        $sourceurl = fetch_wpinstpack($apiurl, $locale, $errtxt, $version);
        if (!$sourceurl) front_exiterror($errtxt);
    }
    if (!empty($packagename)) echo "安装包：".$packagename."<br />";
    if (!empty($version)) echo "版本：<strong>".$version."</strong>"."<br />";
    echo "URL：".htmlentities($sourceurl, ENT_COMPAT, "utf-8");
    echo "</p>"; 
} front_getsourceurl();

function front_download() {
    global $sourceurl, $filename;
    echo "<p>";
    echo "开始下载安装包... ";
    $success = http_request($sourceurl, $errtxt, $filename);
    if ($success) {
        echo "完成. ";
    } else {
        front_exiterror($errtxt);
    }
    echo "</p>";
} front_download();

function front_extract() {
    global $filename;
    echo "<p>";
    echo "开始解压缩... ";
    if (file_exists("./wordpress/")) {
        front_exiterror("目录 \"wordpress\" 已存在，无法解压！ 请检查您的目录中是否曾经解压缩过了WordPress安装包。\n（建议您在空目录中运行本程序）");
    }
    $success = extract_file($filename, $errtxt);
    if ($success) {
        echo "完成. ";
    } else {
        front_exiterror($errtxt);
    }
    echo "</p>";
} front_extract();

function front_strip_subdir() {
    global $filename;
    echo "<p>";
    echo "移除wordpress子目录... ";

    $dir = "./wordpress/";
    if (is_dir($dir)) {
        if ($dh = opendir($dir)) {
            while (($currfile = readdir($dh)) !== false) {
                if ($currfile!="." && $currfile!="..") {
                    if (!file_exists("./".$currfile)) {
                        rename($dir.$currfile, "./".$currfile);
                    } else {
                        front_exiterror("文件 ".$currfile." 已存在！ 请检查您的目录中是否已经安装过了WordPress。\n（建议您在空目录中运行本程序）");
                    }
                }
            }
            closedir($dh);
        }
        rmdir($dir);
    } else {
        front_exiterror("解开的zip包中不含wordpress子目录！(可能不是正确的wordpress安装包)");
    }

    echo "完成. ";
    echo "</p>";
} front_strip_subdir();

function front_strip_zip() {
    global $filename;
    echo "<p>";
    echo "删除zip安装包... ";
    unlink($filename);
    echo "完成. ";
    echo "</p>";
} front_strip_zip();

function front_self_destruction() {
    echo "<p>";
    if ($_POST["selfdel"] == "true") {
        echo "脚本自我销毁... ";
        unlink($_SERVER['SCRIPT_FILENAME']);
        echo "完成. ";
    } else {
        echo '<span class="error">'.'警告：'.'</span>';
        echo nl2br("\n根据您的指令，这个脚本并未自我销毁。\n 任何其他人都可以通过这个脚本上传、解压ZIP文件。\n
            安全起见，建议您尽快手工删除。");
    }
    echo "</p>";
} front_self_destruction();
?>
<h2>安装完成！</h2>
<p>您已成功准备了WordPress程序的所有文件！</p>
<p>接下来，您可以访问您的网站，继续WordPress安装过程：</p>
<p><a href="<?php echo htmlentities(currpath_url(), ENT_COMPAT, "utf-8"); ?>"><?php echo htmlentities(currpath_url(), ENT_COMPAT, "utf-8"); ?></a></p>
<p>感谢您的使用！<br />脚本作者：<a href="http://shamiao.com" title="沙渺很忙WordPress技术博客">沙渺</a></p>
<?php else : ?>
<h2>选择安装源</h2>
<form method="post" action="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<p><input type="radio" name="publish" id="wpcng" value="wpcng" checked="checked" /><label for="wpcng">WordPress 中文团队汉化版 (wpcng.com)</label></p>
<p><input type="radio" name="publish" id="cnoffical" value="cnoffical" /><label for="cnoffical">WordPress 官方中文版 (cn.wordpress.org)</label></p>
<p><input type="radio" name="publish" id="enoffical" value="enoffical" /><label for="enoffical">WordPress 官方英文版 (wordpress.org)</label></p>
<p><input type="radio" name="publish" id="custom" value="custom" /><label for="custom">自定义安装包URL：</label><input name="custurl" id="custurl" type="text" size="45" />（请用.zip格式）<br />
※ 不检测安全性，请自行保证可靠！</p>
<p><input type="submit" value="下载&amp;解压" /> <input type="checkbox" id="selfdel" name="selfdel" value="true" checked="checked" /><label for="selfdel">完成后删除本脚本（建议）</label></p>
<input type="hidden" name="action" value="install" />
</form>
<h2></h2>
<h2>关于 &amp; 授权</h2>
<p>本脚本由沙渺编写。<a href="http://shamiao.com/wp-downunzip">脚本首页</a> <a href="http://sourceforge.net/projects/wpdownunzip/">SourceForge页面</a></p>
<p>作者博客：<a href="http://shamiao.com">沙渺很忙 http://shamiao.com</a> (主题：电子开发与WordPress研究)</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by/2.5/cn/"><img alt="知识共享许可协议" style="border-width:0" src="http://i.creativecommons.org/l/by/2.5/cn/80x15.png" /></a>本作品采用<a rel="license" href="http://creativecommons.org/licenses/by/2.5/cn/">知识共享署名 2.5 中国大陆许可协议</a>进行许可。<br />
您可以任意使用、转载、修改甚至用于商业作品，只需在<strong>任意位置</strong>注明原作者为<strong>沙渺</strong>即可。</p>
<script type="text/javascript">
//<![CDATA[
radioCheck = function() {
    document.getElementById('wpcng').checked = false;
    document.getElementById('cnoffical').checked = false;
    document.getElementById('enoffical').checked = false;
    document.getElementById('custom').checked = true;
};
document.getElementById('custurl').onfocus = radioCheck;

//]]>
</script>
<?php endif; ?>
</body>
</html>
